home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / program / 441 / dlibs12 / exec.c < prev    next >
C/C++ Source or Header  |  1990-11-23  |  5KB  |  237 lines

  1. #include <stdio.h>
  2. #include <osbind.h>
  3. #include <string.h>
  4. #include <basepage.h>
  5. #include <malloc.h>
  6. #include <errno.h>
  7.  
  8. typedef struct
  9.     {
  10.     char        xarg_magic[4];    /* verification value "xArg" */
  11.     int        xargc;            /* argc */
  12.     char        **xargv;          /* argv */
  13.     char        *xiovector;       /* i/o handle status */
  14.     BASEPAGE    *xparent;         /* pointer to parent's basepage */
  15.     }
  16.     XARG;
  17.  
  18. static char     xmagic[] = "xArg";
  19. static char     hex[] = "0123456789ABCDEF";
  20.  
  21. #define    MAXFORK    8        /* maximum number of concurrent fork's */
  22.  
  23. typedef struct
  24.     {
  25.     int        fk_pid;
  26.     char        fk_rv;
  27.     char        fk_xstatus;
  28.     }
  29.     FORK;
  30.  
  31. static    FORK    forktbl[MAXFORK];
  32.  
  33. #define    XS_NORMAL    0x00        /* process terminated normally */
  34. #define    XS_RUNNING    0x7F        /* process still running */
  35.  
  36. static    FORK    *forkp = forktbl;    /* fork() context pointer */
  37. static    int    forkcnt = 0;        /* # of fork's currently active */
  38. static    char    fork_ext[] = ".ttp\0.tos\0.prg\0.app\0";
  39.  
  40. /*
  41.  * Build TOS-style command line image from argv[] list.
  42.  */
  43. int makcmdln(cmdln, argv)
  44.     char *cmdln;
  45.     char **argv;
  46.     {
  47.     register char *p, *q, *e;
  48.     register int argc = 1;
  49.  
  50.     p = cmdln + 1;
  51.     e = cmdln + 127;
  52.     while(q = *++argv)        /* start at argv[1] */
  53.         {
  54.         ++argc;
  55.         while(*q && p < e)
  56.             *p++ = *q++;
  57.         if (p < e)
  58.             *p++ = ' ';
  59.         }
  60.     *p = '\0';
  61.     cmdln[0] = p - (cmdln + 1);     /* store the string length */
  62.     return(argc);                   /* return number of arguments */
  63.     }
  64.  
  65. forkl(pathname, arg0)
  66.     char *pathname, *arg0;
  67.     {
  68.     forkve(pathname, &arg0, NULL);
  69.     }
  70.  
  71. forkle(pathname, arg0)
  72.     char *pathname, *arg0;
  73.     {
  74.     register char **argv = &arg0, *envp;
  75.     register int argc;
  76.     char cmdln[130];
  77.  
  78.     argc = makcmdln(cmdln, argv);
  79.     envp = argv[argc+1];
  80.     return(_exec(pathname, cmdln, argc, argv, envp));
  81.     }
  82.  
  83. int forklp(pathname, arg0)
  84.     char *pathname, *arg0;
  85.     {
  86.     char *pfindfile();
  87.  
  88.     if(pathname = pfindfile(NULL, pathname, fork_ext))
  89.         return(forkve(pathname, &arg0, NULL));
  90.     return(errno = EFILNF);
  91.     }
  92.  
  93. int forklpe(pathname, arg0)
  94.     char *pathname, *arg0;
  95.     {
  96.     register char **argv = &arg0, *envp;
  97.     register int argc;
  98.     char cmdln[130];
  99.     char *pfindfile();
  100.  
  101.     if(pathname = pfindfile(NULL, pathname, fork_ext))
  102.         {
  103.         argc = makcmdln(cmdln, argv);
  104.         envp = argv[argc+1];
  105.         return(_exec(pathname, cmdln, argc, argv, envp));
  106.         }
  107.     return(errno = EFILNF);
  108.     }
  109.  
  110. forkve(pathname, argv, envp)
  111.     char *pathname, **argv, *envp;
  112.     {
  113.     register int argc;
  114.     char cmdln[130];
  115.  
  116.     argc = makcmdln(cmdln, argv);
  117.     return(_exec(pathname, cmdln, argc, argv, envp));
  118.     }
  119.  
  120. forkvpe(pathname, argv, envp)
  121.     char *pathname, **argv, *envp;
  122.     {
  123.     char *pfindfile();
  124.  
  125.     if(pathname = pfindfile(NULL, pathname, fork_ext))
  126.         return(forkve(pathname, argv, envp));
  127.     return(errno = EFILNF);
  128.     }
  129.  
  130. FORK *_fork()
  131. /*
  132.  * create FORK struct for new process and return calculated pid
  133.  */
  134.     {
  135.     register long n;
  136.     register int pid;
  137.     register FORK *fp;
  138.  
  139.     if((forkcnt >= MAXFORK)        /* too many forks already active? */
  140.     || ((n = Malloc(-1L)) <= 0))    /* malloc error? */
  141.         return(NULL);
  142.     n = Malloc(n);            /* get address of next free block */
  143.     Mfree(n);
  144.     fp = forkp++;
  145.     ++forkcnt;
  146.     n += 0x3EL;            /* adjust it */
  147.     pid = (0x7FFF & (n>>8));    /* calculate pid from it */
  148.     fp->fk_pid = pid;        /* initialize process entry */
  149.     fp->fk_xstatus = XS_RUNNING;
  150.     fp->fk_rv = 0;
  151.     return(fp);
  152.     }
  153.  
  154. int _exec(pathname, cmdln, argc, argv, envp)
  155.     char *pathname, *cmdln;
  156.     int argc;
  157.     char **argv, *envp;
  158.     {
  159.     register FORK *fp;
  160.     XARG xarg;
  161.     register XARG *xp = &xarg;
  162.     register char *p;
  163.     register int n;
  164.     register long rv;
  165.     char xenv[16];
  166.  
  167.     if((fp = _fork()) == NULL)
  168.         return(ERROR);
  169.     /*
  170.      * initialize XARG struct
  171.      */
  172.     strncpy(xp->xarg_magic, xmagic, 4);
  173.     xp->xargc = argc;
  174.     xp->xargv = argv;
  175.     xp->xiovector = NULL;
  176.     xp->xparent = _base;
  177.     /*
  178.      * create environment variable "xArg=XXXXXXXX"
  179.      */
  180.     strcpy(xenv, xmagic);
  181.     p = strrchr(xenv, '\0');        /* move to terminating '\0' */
  182.     *p++ = '=';
  183.     rv = ((long) xp);
  184.     for(n=8; n--; rv >>= 4)         /* convert long to ascii-hex */
  185.         p[n] = hex[rv & 0xF];
  186.     p[8] = '\0';
  187.     /*
  188.      * install environment variable and execute program
  189.      */
  190.     putenv(xenv);
  191.     rv = Pexec(0, pathname, cmdln, envp);
  192.     putenv(xmagic);                 /* remove "xArg" from environment */
  193.     if(rv < 0L)            /* GEMDOS error */
  194.         {
  195.         errno = ((int) rv);
  196.         fp->fk_rv = fp->fk_xstatus = ((char) rv);
  197.         }
  198.     else                /* normal exit */
  199.         {
  200.         fp->fk_xstatus = XS_NORMAL;
  201.         fp->fk_rv = ((char) rv);
  202.         }
  203.     return(fp->fk_pid);
  204.     }
  205.  
  206. int wait(rvp)
  207.     char *rvp;
  208.     {
  209.     register FORK *fp;
  210.     register int pid;
  211.  
  212.     fp = forktbl;
  213.     if(fp == forkp)            /* no child processes */
  214.         return(errno = ERROR);
  215.     for(;;)
  216.         {
  217.         for(fp = forktbl; fp < forkp; ++fp)
  218.             {
  219.             if(fp->fk_xstatus != XS_RUNNING)
  220.                 {
  221.                 pid = fp->fk_pid;
  222.                 if(rvp)
  223.                     {
  224.                     rvp[0] = fp->fk_rv;
  225.                     rvp[1] = fp->fk_xstatus;
  226.                     }
  227.                 --forkp;
  228.                 --forkcnt;
  229.                 while(fp++ < forkp)
  230.                     fp[-1] = fp[0];
  231.                 return(pid);
  232.                 }
  233.             }
  234.         sleep(1);
  235.         }
  236.     }
  237.